home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #3 / Amiga Plus CD - 2002 - No. 03.iso / AmiSoft / Util / Sys / Amberram.lha / AmberRAM / Source / notification.c < prev    next >
Encoding:
C/C++ Source or Header  |  2003-01-29  |  8.3 KB  |  445 lines

  1. /*
  2.  
  3. File: notification.c
  4. Author: Neil Cafferkey
  5. Copyright (C) 2001-2003 Neil Cafferkey
  6.  
  7. This program is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU General Public License
  9. as published by the Free Software Foundation; either version 2
  10. of the License, or (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  20. MA 02111-1307, USA.
  21.  
  22. */
  23.  
  24.  
  25. #include "handler_protos.h"
  26.  
  27.  
  28. static VOID NotifyObject(struct Handler *handler,struct Object *object);
  29.  
  30.  
  31.  
  32. /****i* ram.handler/MatchNotifyRequests ************************************
  33. *
  34. *   NAME
  35. *    MatchNotifyRequests --
  36. *
  37. *   SYNOPSIS
  38. *    MatchNotifyRequests(handler)
  39. *
  40. *    VOID MatchNotifyRequests(struct Handler *);
  41. *
  42. *   FUNCTION
  43. *
  44. *   INPUTS
  45. *
  46. *   RESULT
  47. *
  48. *   EXAMPLE
  49. *
  50. *   NOTES
  51. *
  52. *   BUGS
  53. *
  54. *   SEE ALSO
  55. *
  56. ****************************************************************************
  57. *
  58. */
  59.  
  60. VOID MatchNotifyRequests(struct Handler *handler)
  61. {
  62.    struct Notification *notification,*next_notification,*tail;
  63.    struct Object *object;
  64.  
  65.    next_notification=(APTR)handler->notifications.mlh_Head;
  66.    tail=(APTR)&handler->notifications.mlh_Tail;
  67.  
  68.    while(next_notification!=tail)
  69.    {
  70.       notification=next_notification;
  71.       next_notification=(APTR)((struct MinNode *)notification)->mln_Succ;
  72.  
  73.       object=
  74.          GetObject(handler,NULL,notification->request->nr_FullName,NULL);
  75.       if(object!=NULL)
  76.       {
  77.          Remove((APTR)notification);
  78.          AddTail((APTR)&object->notifications,(APTR)notification);
  79.       }
  80.    }
  81.  
  82.    return;
  83. }
  84.  
  85.  
  86.  
  87. /****i* ram.handler/UnmatchNotifyRequests **********************************
  88. *
  89. *   NAME
  90. *    UnmatchNotifyRequests --
  91. *
  92. *   SYNOPSIS
  93. *    UnmatchNotifyRequests(handler,object)
  94. *
  95. *    VOID UnmatchNotifyRequests(struct Handler *,struct Object *);
  96. *
  97. *   FUNCTION
  98. *
  99. *   INPUTS
  100. *
  101. *   RESULT
  102. *
  103. *   EXAMPLE
  104. *
  105. *   NOTES
  106. *
  107. *   BUGS
  108. *
  109. *   SEE ALSO
  110. *
  111. ****************************************************************************
  112. *
  113. */
  114.  
  115. VOID UnmatchNotifyRequests(struct Handler *handler,struct Object *object)
  116. {
  117.    struct Notification *notification,*next_notification,*tail;
  118.  
  119.    next_notification=(APTR)object->notifications.mlh_Head;
  120.    tail=(APTR)&object->notifications.mlh_Tail;
  121.  
  122.    while(next_notification!=tail)
  123.    {
  124.       notification=next_notification;
  125.       next_notification=(APTR)((struct MinNode *)notification)->mln_Succ;
  126.  
  127.       Remove((APTR)notification);
  128.       AddTail((APTR)&handler->notifications,(APTR)notification);
  129.    }
  130.  
  131.    return;
  132. }
  133.  
  134.  
  135. /****i* ram.handler/NotifyAll **********************************************
  136. *
  137. *   NAME
  138. *    NotifyAll --
  139. *
  140. *   SYNOPSIS
  141. *    NotifyAll(handler,object,notify_links)
  142. *
  143. *    VOID NotifyAll(struct Handler *,struct Object *,BOOL);
  144. *
  145. *   FUNCTION
  146. *
  147. *   INPUTS
  148. *
  149. *   RESULT
  150. *
  151. *   EXAMPLE
  152. *
  153. *   NOTES
  154. *
  155. *   BUGS
  156. *
  157. *   SEE ALSO
  158. *
  159. ****************************************************************************
  160. *
  161. */
  162.  
  163. VOID NotifyAll(struct Handler *handler,struct Object *object,
  164.    BOOL notify_links)
  165. {
  166.    struct MinNode *tail,*link_node;
  167.  
  168.    if(notify_links)
  169.    {
  170.       object=GetRealObject(object);
  171.       link_node=object->hard_link.mln_Succ;
  172.       if(link_node!=NULL)
  173.       {
  174.          tail=(APTR)&HARDLINK(link_node)->elements.mlh_Tail;
  175.       }
  176.       else
  177.          notify_links=FALSE;
  178.    }
  179.  
  180.    if(notify_links)
  181.    {
  182.       link_node=&object->hard_link;
  183.  
  184.       while(link_node!=tail)
  185.       {
  186.          object=HARDLINK(link_node);
  187.          NotifyObject(handler,object);
  188.          NotifyObject(handler,object->parent);
  189.          link_node=link_node->mln_Succ;
  190.       }
  191.    }
  192.    else
  193.    {
  194.       NotifyObject(handler,object);
  195.       NotifyObject(handler,object->parent);
  196.    }
  197.  
  198.    return;
  199. }
  200.  
  201.  
  202.  
  203. /****i* ram.handler/NotifyObject *******************************************
  204. *
  205. *   NAME
  206. *    NotifyObject --
  207. *
  208. *   SYNOPSIS
  209. *    NotifyObject(handler,object)
  210. *
  211. *    VOID NotifyObject(struct Handler *,struct Object *);
  212. *
  213. *   FUNCTION
  214. *
  215. *   INPUTS
  216. *
  217. *   RESULT
  218. *
  219. *   EXAMPLE
  220. *
  221. *   NOTES
  222. *
  223. *   BUGS
  224. *
  225. *   SEE ALSO
  226. *
  227. ****************************************************************************
  228. *
  229. */
  230.  
  231. static VOID NotifyObject(struct Handler *handler,struct Object *object)
  232. {
  233.    struct Notification *notification,*tail;
  234.  
  235.    if(object!=NULL)
  236.    {
  237.       notification=(APTR)object->notifications.mlh_Head;
  238.       tail=(APTR)&object->notifications.mlh_Tail;
  239.  
  240.       while(notification!=tail)
  241.       {
  242.          Notify(handler,notification);
  243.          notification=(APTR)((struct MinNode *)notification)->mln_Succ;
  244.       }
  245.    }
  246.  
  247.    return;
  248. }
  249.  
  250.  
  251.  
  252. /****i* ram.handler/FindNotification ***************************************
  253. *
  254. *   NAME
  255. *    FindNotification --
  256. *
  257. *   SYNOPSIS
  258. *    notification = FindNotification(handler,
  259. *        request)
  260. *
  261. *    struct Notification *FindNotification(struct Handler *,
  262. *        struct NotifyRequest);
  263. *
  264. *   FUNCTION
  265. *
  266. *   INPUTS
  267. *
  268. *   RESULT
  269. *
  270. *   EXAMPLE
  271. *
  272. *   NOTES
  273. *
  274. *   BUGS
  275. *
  276. *   SEE ALSO
  277. *
  278. ****************************************************************************
  279. *
  280. */
  281.  
  282. struct Notification *FindNotification(struct Handler *handler,
  283.    struct NotifyRequest *request)
  284. {
  285.    struct Notification *notification,*tail;
  286.    struct MinList *list;
  287.    BOOL found;
  288.    struct Object *object;
  289.  
  290.    /* Find which list the request should be in */
  291.  
  292.    object=GetObject(handler,NULL,request->nr_FullName,NULL);
  293.    if(object!=NULL)
  294.       list=&object->notifications;
  295.    else
  296.       list=&handler->notifications;
  297.  
  298.    /* Search the list */
  299.  
  300.    notification=(APTR)list->mlh_Head;
  301.    tail=(APTR)&list->mlh_Tail;
  302.    found=FALSE;
  303.  
  304.    while((notification!=tail)&&!found)
  305.    {
  306.       if(notification->request==request)
  307.          found=TRUE;
  308.       else
  309.          notification=(APTR)((struct MinNode *)notification)->mln_Succ;
  310.    }
  311.  
  312.    if(!found)
  313.       notification=NULL;
  314.  
  315.    return notification;
  316. }
  317.  
  318.  
  319.  
  320. /****i* ram.handler/ReceiveNotifyReply *************************************
  321. *
  322. *   NAME
  323. *    ReceiveNotifyReply --
  324. *
  325. *   SYNOPSIS
  326. *    ReceiveNotifyReply(handler,message)
  327. *
  328. *    VOID ReceiveNotifyReply(struct Handler *,struct NotifyMessage *);
  329. *
  330. *   FUNCTION
  331. *
  332. *   INPUTS
  333. *
  334. *   RESULT
  335. *
  336. *   EXAMPLE
  337. *
  338. *   NOTES
  339. *
  340. *   BUGS
  341. *
  342. *   SEE ALSO
  343. *
  344. ****************************************************************************
  345. *
  346. */
  347.  
  348. VOID ReceiveNotifyReply(struct Handler *handler,
  349.    struct NotifyMessage *message)
  350. {
  351.    struct Notification *notification;
  352.    struct NotifyRequest *request;
  353.  
  354.    request=message->nm_NReq;
  355.    notification=FindNotification(handler,request);
  356.    FreeMem(message,sizeof(struct NotifyMessage));
  357.  
  358.    if(notification!=NULL)
  359.    {
  360.       request->nr_MsgCount--;
  361.  
  362.       if(request->nr_Flags&NRF_MAGIC)
  363.       {
  364.          request->nr_Flags&=~NRF_MAGIC;
  365.          Notify(handler,notification);
  366.       }
  367.    }
  368.  
  369.    return;
  370. }
  371.  
  372.  
  373.  
  374. /****i* ram.handler/Notify *************************************************
  375. *
  376. *   NAME
  377. *    Notify --
  378. *
  379. *   SYNOPSIS
  380. *    Notify(handler,notification)
  381. *
  382. *    VOID Notify(struct Handler *,struct Notification *);
  383. *
  384. *   FUNCTION
  385. *
  386. *   INPUTS
  387. *
  388. *   RESULT
  389. *
  390. *   EXAMPLE
  391. *
  392. *   NOTES
  393. *
  394. *   BUGS
  395. *
  396. *   SEE ALSO
  397. *
  398. ****************************************************************************
  399. *
  400. */
  401.  
  402. VOID Notify(struct Handler *handler,struct Notification *notification)
  403. {
  404.    struct NotifyMessage *message;
  405.    struct NotifyRequest *request;
  406.    ULONG flags;
  407.  
  408.    request=notification->request;
  409.    flags=request->nr_Flags;
  410.    if((flags&NRF_SEND_MESSAGE)!=0)
  411.    {
  412.       /* Send message now or remember to send it later */
  413.  
  414.       if(((flags&NRF_WAIT_REPLY)==0)||(request->nr_MsgCount==0))
  415.       {
  416.          message=AllocMem(sizeof(struct NotifyMessage),
  417.             MEMF_PUBLIC|MEMF_CLEAR);
  418.          if(message!=NULL)
  419.          {
  420.             ((struct Message *)message)->mn_ReplyPort=handler->notify_port;
  421.             ((struct Message *)message)->mn_Length=
  422.                sizeof(struct NotifyMessage);
  423.             message->nm_NReq=request;
  424.             message->nm_Class=NOTIFY_CLASS;
  425.             message->nm_Code=NOTIFY_CODE;
  426.  
  427.             PutMsg(request->nr_stuff.nr_Msg.nr_Port,(APTR)message);
  428.             request->nr_MsgCount++;
  429.          }
  430.       }
  431.       else
  432.          request->nr_Flags|=NRF_MAGIC;
  433.    }
  434.    else
  435.    {
  436.       Signal(request->nr_stuff.nr_Signal.nr_Task,
  437.          1<<(request->nr_stuff.nr_Signal.nr_SignalNum));
  438.    }
  439.  
  440.    return;
  441. }
  442.  
  443.  
  444.  
  445.